/*
 * @Author: zhanwei xu
 * @Date: 2023-06-24 22:05:54
 * @LastEditors: zhanwei xu
 * @LastEditTime: 2023-06-28 02:23:33
 * @Description: 
 * 
 * Copyright (c) 2023 by zhanwei xu, Tsinghua University, All Rights Reserved. 
 */
import { appRef } from "@/models/app.ref";
import { BaseServices } from "./base.services";
import { Method, Uri, RespInfo, config } from "./config";
import { RoleEnum } from "@/models/@types";
import { ModelApiEnum, ModelApiEnumOption} from "@/models/chat-work";

export class WorkService extends BaseServices {
  private static _ins: WorkService = new WorkService();
  public static get ins(): WorkService {
    return this._ins ? this._ins : (this._ins = new WorkService());
  }

  public sendstream(question: string, chunk: (data: string) => void, callback: () => void): void {
    const questionUid = appRef.chatWork.addMenuAnswer(RoleEnum.User, question);
    const modelOption = ModelApiEnumOption.find((option) => option.key === appRef.chatWork.currMenu.modelapi);
    const modelText = modelOption ? modelOption.model : 'v3.5';
    var url = modelOption.url;
    var data = {
      message: appRef.chatWork.currMenu.sessions.map(({ role, richtext }) => ({
        role,
        content: richtext
      })),
      mode: modelText,
      key: appRef.user.data.openai_key
    };
    return this.stream(url, data, chunk, (data: string) => {
      callback();
      appRef.chatWork.addMenuAnswer(RoleEnum.AI, data.toString(), questionUid);
    });
  }

  /** 发送消息 */
  public send(question: string): Promise<string> {
    const questionUid = appRef.chatWork.addMenuAnswer(RoleEnum.User, question);
    const modelOption = ModelApiEnumOption.find((option) => option.key === appRef.chatWork.currMenu.modelapi);
    const modelText = modelOption ? modelOption.model : 'v3.5';
    var url = modelOption.url;
    var data = {
      message: appRef.chatWork.currMenu.sessions.map(({ role, richtext }) => ({
        role,
        content: richtext
      })),
      mode: modelText,
      key: appRef.user.data.openai_key
    };
    const messageLength = data.message.length;
    data.message[messageLength - 1].role = RoleEnum.User;
    data.message[messageLength - 1].content = question;
    return new Promise<string>((reslove, reject) => {
      this.request(url, data)
        .then(async (res: { answer: string }) => {
          
          console.log(res.toString());
          appRef.chatWork.addMenuAnswer(RoleEnum.AI, res.toString(), questionUid);
          reslove(res.toString());
        })
        .catch((err) => {
          appRef.chatWork.addMenuAnswer(RoleEnum.AI, `Error sending message. Please try again. <br> ${err.stack}`, questionUid);
          reject(err.stack);
        });
    });
  }
  /** 重新发送消息 */
  public refreshSend(quote: string): Promise<string> {
    const currSession = appRef.chatWork?.currMenu?.sessions?.find((val) => val.quote === quote);
    const session = appRef.chatWork?.currMenu?.sessions?.find((val) => val.uid === quote);
    const modelOption = ModelApiEnumOption.find((option) => option.key === appRef.chatWork.currMenu.modelapi);
    const modelText = modelOption ? modelOption.model : 'v3.5';
    var url = modelOption.url;
    const currSessionIndex = appRef.chatWork?.currMenu?.sessions?.findIndex((val) => val.quote === quote);
    const sessionsBeforeCurr = appRef.chatWork.currMenu.sessions.slice(0, currSessionIndex);
    const data = {
      message: sessionsBeforeCurr.map(({ role, richtext }) => ({
        role,
        content: richtext
      })),
      mode: modelText,
      key: appRef.user.data.openai_key
    };
    console.log(data);

    return new Promise<string>((reslove) => {
      this.request(url, data)
        .then(async (res: { answer: string }) => {
          console.log(res)
          appRef.chatWork.removeMenuAnswer(currSession.uid, false);
          appRef.chatWork.addMenuAnswer(RoleEnum.AI, res.toString(), quote);
          reslove(res.toString());
        })
        .catch((err) => {
          console.log(err)
          appRef.chatWork.removeMenuAnswer(session.uid, false);
          appRef.chatWork.addMenuAnswer(RoleEnum.AI, `Error sending message. Please try again. <br> ${err.stack}`, quote);
          reslove(err.stack);
        });
    });
  }
}

export const workService: WorkService = WorkService.ins;
